package com.study.juc.cf;

import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @program: juc-study
 * @author: Zhoujian
 * @date: 2022-08-11 19:57
 * @version: 1.0
 * @description:
 * 1 需求：
 *   1.1 同一款产品，同时搜索出同款产品在各大电商平台的售价
 *   1.2 同一款产品，同时售出本产品在同一个电商平台下，各个入住卖家售价是多少
 *
 * 2 输出：出来结果希望是同款产品的不同地方的价格清单列表，返回一个List<String>
 * 3 技术要求
 *   3.1 函数式编程
 *   3.2 链式编程
 *   3.3 Stream流式计算
 **/
public class CompletableFutureMallDemo {

	static List<NetMall> list = Arrays.asList(
			new NetMall("jd"),
			new NetMall("tmall"),
			new NetMall("pdd"),
			new NetMall("taobao"),
			new NetMall("sn"),
			new NetMall("mi")
	);

	/**
	 * step by step 一家家搜 功能实现
	 * @param list
	 * @param productName
	 * @return
	 */
	public static List<String> getPrice(List<NetMall> list,String productName){
		return list.stream()
				.map(netMall ->
						String.format(productName + " in %s price is %.2f",
								netMall.getNetMallName(),netMall.getPriceByName(productName)))
				.collect(Collectors.toList());
	}

	/**
	 * 性能 多线程
	 * @param list
	 * @param productName
	 * @return
	 */
	public static List<String> getPriceByCompletableFuture(List<NetMall> list,String productName){
		List<CompletableFuture<String>> collect = list
				.stream()
				.map(netMall ->
						CompletableFuture.supplyAsync(() ->
								String.format(productName + " in %s price is %.2f",
										netMall.getNetMallName(), netMall.getPriceByName(productName))))
				.collect(Collectors.toList());

		return collect.stream()
				.map(CompletableFuture::join)
				.collect(Collectors.toList());
 	}

	public static void main(String[] args) {
		gongneng();
		System.out.println("-------------------");
		xingneng();
	}

	private static void xingneng() {
		long startTime2 = System.currentTimeMillis();
		List<String> list2 = getPriceByCompletableFuture(list, "thinking in java");
		for (String element : list2) {
			System.out.println(element);
		}
		long endTime2 = System.currentTimeMillis();
		System.out.println("----costTime: "+(endTime2 - startTime2) +" 毫秒");
	}

	/**
	 * 只是完成了功能需求，单线程跑任务
	 */
	private static void gongneng() {
		long startTime = System.currentTimeMillis();
		List<String> jd = getPrice(list, "mysql");
		jd.forEach(System.out::println);
		long endTime = System.currentTimeMillis();
		System.out.println("----costTime: "+(endTime - startTime) +" 毫秒");
	}
}

class NetMall{
	@Getter
	private String netMallName;

	public NetMall(String netMallName){
		this.netMallName = netMallName;
	}

	public double getPriceByName(String productName){
		return calcPrice(productName);
	}

	/**
	 * 生成价格 每次调用使用 随机数 + 首字母char值 生成价格
	 * @param productName
	 * @return
	 */
	private double calcPrice(String productName) {
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
	}
}
